﻿using Bilibili.Common.Api;
using Bilibili.Model.Bangumi;
using Bilibili.Model.Common;
using Bilibili.Model.Resource;
using Newtonsoft.Json.Linq;
using PCLUntils.Json;
using PCLUntils.Objects;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace Bilibili.WebClient.Api
{
    public sealed class BangmiClient : ClientBase
    {
        public async Task<ReturnModel<MyBangumi>> GetMyFllow(int pageIndex)
        {
            try
            {
                ApiInfo apiInfo = new ApiInfo("http://bangumi.bilibili.com/api/get_concerned_season", $"&page={pageIndex}&pagesize=10", true, true);
                string results = await ApiClient.GetResultsUTF8Encode(apiInfo);
                MyBangumi m = results.ParseObject<MyBangumi>();
                return BuildSuccessResult(m);
            }
            catch (Exception ex)
            {
                return BuildExceptionResult<MyBangumi>(ex);
            }
        }
        public async Task<ReturnModel<JObject>> Condition(int typeId)
        {
            try
            {
                ApiInfo apiInfo = new ApiInfo("https://bangumi.bilibili.com/media/api/search/v2/condition", $"&season_type={typeId}", true);
                string results = await ApiClient.GetResultsUTF8Encode(apiInfo);
                var data = results.ToJObject();
                return BuildSuccessResult(data);
            }
            catch (Exception ex)
            {
                return BuildExceptionResult<JObject>(ex);
            }
        }
        public async Task<ReturnModel<BangmiHome>> GetHome(int type)
        {
            try
            {
                var url = type == 0 ? "https://bangumi.bilibili.com/appindex/followjp_index_page" :
                    "https://bangumi.bilibili.com/appindex/followcn_index_page";
                ApiInfo apiInfo = new ApiInfo(url, true);
                string results = await ApiClient.GetResultsUTF8Encode(apiInfo);
                var m = results.ParseObject<BangmiHome>();
                return BuildSuccessResult(m);
            }
            catch (Exception ex)
            {
                return BuildExceptionResult<BangmiHome>(ex);
            }
        }
        public async Task<ReturnModel<List<TimeLine>>> GetTimeline(int type)
        {
            try
            {
                var url = $"https://bangumi.bilibili.com/web_api/{(type == 1 ? "timeline_global" : "timeline_cn")}";
                string results = await ApiClient.GetResultsUTF8Encode(url);
                var obj = results.ToJObject();
                if (obj["code"].ToInt32() == 0)
                {
                    var model = obj["result"].ParseObject<List<TimeLine>>();
                    return BuildSuccessResult(model);
                }
                else
                    return BuildFailedResult<List<TimeLine>>(obj["message"].ToString());
            }
            catch (Exception ex)
            {
                return BuildExceptionResult<List<TimeLine>>(ex);
            }
        }
        public async Task<ReturnModel> MoveStatus(int seasonId, int status)
        {
            try
            {
                DataInfo dataInfo = new DataInfo($"season_id={seasonId}&status={status}", ApiProviderBase.Build5);
                string results = await ApiClient.PostResults("https://api.bilibili.com/pgc/app/follow/status/update", dataInfo.ToString());
                var json = results.ToJObject();
                if (json.IsNotEmpty())
                {
                    if (json["code"].ToInt32() == 0)
                        return BuildSuccessResult();
                    else
                        return BuildFailedResult(json["message"].ToString());
                }
                else
                    return BuildFailedResult();
            }
            catch (Exception ex)
            {
                return BuildExceptionResult(ex);
            }
        }
        public async Task<ReturnModel<BangumiHome>> GetRecommand()
        {
            try
            {
                ApiInfo apiInfo = new ApiInfo("https://bangumi.bilibili.com/appindex/follow_index_page", false);
                string results = await ApiClient.GetResultsUTF8Encode(apiInfo);
                var pbj = results.ToJObject();
                if (pbj["code"].ToInt32() == 0)
                {
                    BangumiHome m = pbj["result"].ParseObject<BangumiHome>();
                    return BuildSuccessResult(m);
                }
                return BuildFailedResult<BangumiHome>(pbj["message"].ToString());
            }
            catch (Exception ex)
            {
                return BuildExceptionResult<BangumiHome>(ex);
            }
        }
        public async Task<ReturnModel<BangumiDetail>> GetDetail(int mediaId)
        {
            try
            {
                ApiInfo apiInfo = new ApiInfo("https://bangumi.bilibili.com/media/api/detail", $"&media_id={mediaId}", false);
                var results = await ApiClient.GetResults(apiInfo);
                var bangumiDetailModel = results.ParseObject<BangumiDetail>();
                if (bangumiDetailModel.IsNotEmpty())
                {
                    if (bangumiDetailModel.Code == 0)
                    {
                        var model = bangumiDetailModel.Result;
                        return BuildSuccessResult(model);
                    }
                }
                return BuildFailedResult<BangumiDetail>();
            }
            catch (Exception ex)
            {
                return BuildExceptionResult<BangumiDetail>(ex);
            }
        }
        public async Task<ReturnModel<BangumiData>> GetInfo(string bangmiId)
        {
            try
            {
                ApiInfo apiInfo = new ApiInfo("https://api.bilibili.com/pgc/view/app/season", $"&season_id={bangmiId}", true);
                var results = await ApiClient.GetResultsUTF8Encode(apiInfo);
                var model = results.ParseObject<BangumiData>();
                return BuildSuccessResult(model, results);
            }
            catch (Exception ex)
            {
                return BuildExceptionResult<BangumiData>(ex);
            }
        }
        public async Task<ReturnModel<T>> GetInfnFromPlus<T>(string bangmiId)
        {
            try
            {
                string eresults = await ApiClient.GetResultsUTF8Encode("https://bangumi.bilibili.com/view/web_api/season?season_id=" + bangmiId);
                T model = default;
                if (typeof(T).Name.IndexOf("bangumidata", StringComparison.OrdinalIgnoreCase) >= 0)
                    model = eresults.Replace("ep_id", "episode_id").Replace("cid", "danmaku").Replace("aid", "av_id").ParseObject<T>();
                else
                    model = eresults.Replace("ep_id", "episode_id").Replace("cid", "danmaku").Replace("aid", "av_id").Replace("index_title", "long_title").
                                   Replace("index", "title").ToJObject()["result"]["episodes"].ToObject<T>();
                return BuildSuccessResult(model);
            }
            catch (Exception ex)
            {
                return BuildExceptionResult<T>(ex);
            }
        }
        public async Task<ReturnModel> CancelFollow(int seasonId, int seasonType)
        {
            try
            {
                ApiInfo apiInfo = new ApiInfo("https://bangumi.bilibili.com/follow/api/season/unfollow", $"&season_id={seasonId}&season_type={seasonType}", true);
                string results = await ApiClient.GetResults(apiInfo);
                var json = results.ToJObject();
                if (json.IsNotEmpty())
                {
                    if (json["code"].ToInt32() == 0)
                        return BuildSuccessResult();
                    else
                        return BuildFailedResult(json["message"].ToString());
                }
                else
                {
                    return BuildFailedResult();
                }
            }
            catch (Exception ex)
            {
                return BuildExceptionResult(ex);
            }
        }
        public async Task<ReturnModel<BanTJModel>> GetRecommand(string type)
        {
            try
            {
                var url = $"https://api.bilibili.com/pgc/web/rank/list?day=3&season_type={type}";
                string results = await ApiClient.GetResultsUTF8Encode(url);
                var m = results.ParseObject<BanTJModel>();
                return BuildSuccessResult(m);
            }
            catch (Exception ex)
            {
                return BuildExceptionResult<BanTJModel>(ex);
            }
        }
        public async Task<ReturnModel<JObject>> GetFollow(SeasonType seasonType, int pn, int status)
        {
            try
            {
                ApiInfo apiInfo = new ApiInfo($"https://api.bilibili.com/pgc/app/follow/v2/{seasonType}", $"&pn={pn}&ps=20&status={status}", true);
                var result = await ApiClient.GetResults(apiInfo);
                var obj = result.ToJObject();
                return BuildSuccessResult(obj);
            }
            catch (Exception ex)
            {
                return BuildExceptionResult<JObject>(ex);
            }
        }
        public async Task<ReturnModel<AllBangmi>> GetBangmiTag(string conditions, int typeId, int pageNum)
        {
            try
            {
                ApiInfo apiInfo = new ApiInfo("https://bangumi.bilibili.com/media/api/search/result", $"&sort=0&page={pageNum}&pagesize=24&season_type={typeId}{conditions}", false);
                var results = await ApiClient.GetResults(apiInfo);
                var m = results.ParseObject<AllBangmi>();
                return BuildSuccessResult(m);
            }
            catch (Exception ex)
            {
                return BuildExceptionResult<AllBangmi>(ex);
            }
        }
    }
}